package com.jzoom.zoom.admin.modules;


import com.jzoom.zoom.admin.annotations.IgnoreOutput;
import com.jzoom.zoom.admin.controllers.AdminController;
import com.jzoom.zoom.admin.interceptors.AdminActionInterceptor;
import com.jzoom.zoom.aop.AopFactory;
import com.jzoom.zoom.aop.MethodInterceptor;
import com.jzoom.zoom.aop.MethodInvoker;
import com.jzoom.zoom.aop.annotations.AopEnable;
import com.jzoom.zoom.cache.annotations.CacheEnable;
import com.jzoom.zoom.common.annotations.Inject;
import com.jzoom.zoom.common.annotations.IocBean;
import com.jzoom.zoom.common.annotations.Module;
import com.jzoom.zoom.common.filter.ClassAndMethodFilter;
import com.jzoom.zoom.common.json.JSON;
import com.jzoom.zoom.plugin.annotations.PluginEnable;
import com.jzoom.zoom.timer.annotation.TimerEnable;
import com.jzoom.zoom.web.action.ActionContext;
import com.jzoom.zoom.web.action.ActionInterceptorFactory;
import com.jzoom.zoom.web.annotations.Controller;
import com.jzoom.zoom.web.annotations.JsonResponse;
import com.jzoom.zoom.web.annotations.ZoomApplication;
import com.jzoom.zoom.web.view.impl.StringView;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.Method;


@TimerEnable
@AopEnable
@PluginEnable
@CacheEnable
@ZoomApplication
@Module
public class Application {

    private static final Log log = LogFactory.getLog(Application.class);


    public Application() {

    }


    @Inject
    public void config(AopFactory aopFactory) {
        aopFactory.addFilter(new MethodInterceptor() {
            @Override
            public void intercept(MethodInvoker invoker) throws Throwable {
                ActionContext actionContext = ActionContext.get();
                try {
                    log.info("正在访问" + actionContext.getRequest().getServletPath());

                    invoker.invoke();
                    Object result = invoker.getReturnObject();
                    if (result instanceof StringView) {
                        log.info("返回值" + actionContext.getRequest().getServletPath() + ((StringView) result).getStr());
                    } else {
                        log.info("返回值" + actionContext.getRequest().getServletPath() + JSON.stringify(result));
                    }

                } catch (Throwable e) {

                    log.error("发生错误" + actionContext.getRequest().getServletPath(), e);


                    throw e;

                }

            }
        }, new ClassAndMethodFilter() {
            @Override
            public boolean accept(Class<?> clazz) {
                return clazz.isAnnotationPresent(Controller.class);
            }

            @Override
            public boolean accept(Class<?> clazz, Method method) {
                return (clazz.isAnnotationPresent(JsonResponse.class)
                        || method.isAnnotationPresent(JsonResponse.class)
                        || method.getReturnType() == StringView.class) && !method.isAnnotationPresent(IgnoreOutput.class);
            }
        }, 0);
    }


    @IocBean
    public AdminActionInterceptor getAdminActionInterceptor() {
        return new AdminActionInterceptor();
    }

    @Inject
    public void config(ActionInterceptorFactory factory, AdminActionInterceptor adminActionInterceptor) {
        factory.add(adminActionInterceptor, new ClassAndMethodFilter() {

            @Override
            public boolean accept(Class<?> clazz, Method method) {
                return true;
            }

            @Override
            public boolean accept(Class<?> clazz) {
                return AdminController.class.isAssignableFrom(clazz);
            }
        }, 1);


    }


}
 